package com.zjsru.plan2025.oneday;

import java.util.Arrays;

/**
 * 2502. 设计内存分配器
 *
 * @Author: cookLee
 * @Date: 2025-02-25
 */
public class Allocator {

    /**
     * 主
     * \
     * 输入
     * ["Allocator", "allocate", "allocate", "allocate", "freeMemory", "allocate", "allocate", "allocate", "freeMemory", "allocate", "freeMemory"]
     * [[10], [1, 1], [1, 2], [1, 3], [2], [3, 4], [1, 1], [1, 1], [1], [10, 2], [7]]
     * 输出
     * [null, 0, 1, 2, 1, 3, 1, 6, 3, -1, 0]
     * <p>
     * 解释
     * Allocator loc = new Allocator(10); // 初始化一个大小为 10 的内存数组，所有内存单元都是空闲的。
     * loc.allocate(1, 1); // 最左侧的块的第一个下标是 0 。内存数组变为 [1, , , , , , , , , ]。返回 0 。
     * loc.allocate(1, 2); // 最左侧的块的第一个下标是 1 。内存数组变为 [1,2, , , , , , , , ]。返回 1 。
     * loc.allocate(1, 3); // 最左侧的块的第一个下标是 2 。内存数组变为 [1,2,3, , , , , , , ]。返回 2 。
     * loc.freeMemory(2); // 释放 mID 为 2 的所有内存单元。内存数组变为 [1, ,3, , , , , , , ] 。返回 1 ，因为只有 1 个 mID 为 2 的内存单元。
     * loc.allocate(3, 4); // 最左侧的块的第一个下标是 3 。内存数组变为 [1, ,3,4,4,4, , , , ]。返回 3 。
     * loc.allocate(1, 1); // 最左侧的块的第一个下标是 1 。内存数组变为 [1,1,3,4,4,4, , , , ]。返回 1 。
     * loc.allocate(1, 1); // 最左侧的块的第一个下标是 6 。内存数组变为 [1,1,3,4,4,4,1, , , ]。返回 6 。
     * loc.freeMemory(1); // 释放 mID 为 1 的所有内存单元。内存数组变为 [ , ,3,4,4,4, , , , ] 。返回 3 ，因为有 3 个 mID 为 1 的内存单元。
     * loc.allocate(10, 2); // 无法找出长度为 10 个连续空闲内存单元的空闲块，所有返回 -1 。
     * loc.freeMemory(7); // 释放 mID 为 7 的所有内存单元。内存数组保持原状，因为不存在 mID 为 7 的内存单元。返回 0 。
     * \
     *
     * @param args args
     */
    public static void main(String[] args) {

    }

    private int n;
    private int[] memory;

    /**
     * 分配器
     * Allocator(int n) 使用一个大小为 n 的内存数组初始化 Allocator 对象。
     *
     * @param n n
     */
    public Allocator(int n) {
        this.n = n;
        this.memory = new int[n];
    }

    /**
     * 分配
     * int allocate(int size, int mID) 找出大小为 size 个连续空闲内存单元且位于  最左侧 的块，分配并赋 id mID 。返回块的第一个下标。如果不存在这样的块，返回 -1 。
     *
     * @param size 尺寸
     * @param mID  m id
     * @return int
     */
    public int allocate(int size, int mID) {
        int count = 0;
        for (int i = 0; i < this.n; i++) {
            //已分配内存
            if (this.memory[i] > 0) {
                count = 0;
                continue;
            }
            count++;
            //有足够空位分配
            if (size == count) {
                //起始下标
                int start = i - size + 1;
                Arrays.fill(this.memory, start, i + 1, mID);
                return start;
            }
        }
        return -1;
    }

    /**
     * 可用内存
     * int freeMemory(int mID) 释放 id mID 对应的所有内存单元。返回释放的内存单元数目。
     *
     * @param mID m id
     * @return int
     */
    public int freeMemory(int mID) {
        int count = 0;
        for (int i = 0; i < this.n; i++) {
            if (this.memory[i] == mID) {
                //释放内存
                this.memory[i] = 0;
                count++;
            }
        }
        return count;
    }

}
